<?php

namespace App\Console\Cron;

use App\Models\DispatchWind;
use App\Models\User;
use App\Models\Wind;
use App\Service\Xunsearch\Xunsearch;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class Dispatch extends Command
{
    /**
     * 请求：
     *  php artisan command:cron-dispatch
     *  sudo -u www php /www/wwwroot/slh/laravel.test/artisan command:cron-dispatch
     *
     */
    /**
     * 参数与选项的区别
     *      在执行命令时，参数必须严格按定义时的顺序输入，不需输入参数名，只需输入参数的值即可。
     *      输入选项则必须带选项名，且选项名前须加 -- 前缀（选项简写字母前加 -），选项可按任意顺序输入
     */

    // 请求 以及参数
    // protected $signature = 'command:name {param1} {param2}';  // 必填参数
    // protected $signature = 'command:name {参数名?} {参数名=默认值} {参数名? : 参数说明}';  // 可选参数
    // protected $signature = 'command:name {--选项名} {--选项名=} {--选项名=默认值} {--简写字母|选项名} {--选项名 : 选项说明}';  // 选项
    protected $signature = 'command:cron-dispatch';

    protected $description = '定时任务：从财通社采集快讯数据';  // TODO 定时任务
    protected $ctsDb;
    protected $toDb;

    public function __construct()
    {
        parent::__construct();
    }

    // 执行的命令
    public function handle()
    {
        $this->toMigration();
    }

    // 执行迁移
    protected function toMigration()
    {
        $shlTable = 'dispatch';
        $num      = 100;
        $start    = 2200000;
        $id_sql   = "SELECT max(news_id) as max_id FROM `shl_$shlTable`  order by id DESC limit 0,1 ; ";
        $ids      = $this->toDb()->select($id_sql);
        if(!empty($ids[0]) && (!is_null($ids[0]->max_id))){
            $start = $ids[0]->max_id;
        }

        // 获取财通社快讯
        $this->line('获取迁移数据第'.$start.'条开始，获取'.$num.'条');
        $result  = $this->ctsData($start, $num);
        $lists   = $result['list'];
        $is_next = $result['is_next'];
        if(empty($lists)){
            return $this->line('没有数据需要迁移！');
        }

        // 获取所有的风向标信息
        $winds = $this->getWinds();

        $this->line('  共获取到'.count($lists).'条');
        // 保存快讯
        $insert = [];
        foreach($lists as $key => $item){
            // 内容处理
            $brief = $item['brief'];
            if(mb_substr($brief, 0, 1) == "【"){
                $pos     = mb_strpos($brief, "】");
                $content = mb_substr($brief, $pos + 1);
                $title   = mb_substr($brief, 1, $pos - 1);
                $title   = mb_substr($title, 0, 150);
            } else{
                $content = $brief;
                $title   = '';
            }
            // 如果超过 500 个字 则不要
            if(mb_strlen($content) > 500){
                continue;
            }


            // 匹配文章的话题标签
            $dWinsDb   = new DispatchWind();
            $windMatch = $dWinsDb->contentMatchWind($winds, $content);
            $_winds    = $windMatch['winds'];
            $_keyword  = $windMatch['keyword'];

            // 组合数据
            $images = $item['images'] ?: json_encode([]);
            $row    = [
                'news_id'  => $item['id'],
                'is_major' => $item['is_major'] == 'enabled' ? 1 : 0,
                'title'    => $title,
                'content'  => $content,
                'verify'   => 1,
                'uid'      => 11019,
                'images'   => $images,
                'ctime'    => $item['create_time'],
                'mtime'    => $item['create_time'],
                'keywords' => json_encode($_keyword, JSON_UNESCAPED_UNICODE),
                //'origin_id' => 'originNewsId',
            ];

            // 保存快讯
            $dispaDb = new \App\Models\Dispatch();
            $dis_id  = $dispaDb->insertGetId($row);
            // 保存快讯的风向标
            $dWinsDb->addDispatchWinds($dis_id, $_winds, 0, 0, $item['create_time']);

            // 组合数据
            $insert[] = $row;
        }
        // 执行操作
        // 更新发布数据
        //$this->toDb()->table($shlTable)->insert($insert);
        $number = ['publish_no' => DB::raw("publish_no+".count($insert))];
        $userDb = new \App\Models\User();
        $userDb->where('id', 1)->update($number);

        // 添加到搜索引擎
        $this->xunsearch($start, $num);

        // 缓存操作
        $dispaDb->deleteCacheList($insert);
        $userDb->deleteCacheshow(['id' => 1]);

        // 保存日志
        $this->sqlLog();
        if($is_next){
            return $this->toMigration();
        }

        return $this->line('数据需要迁移完成！');
    }

    // 获取财通社数据
    protected function ctsData($start, $num)
    {
        $url = "http://newapi.caitongnews.com/v2/slh/dispatch";
        //$url  = "http://api.ctsnews.com/v2/slh/dispatch";  // 本地电脑
        $data = ['page' => 1, 'size' => $num, 'maxId' => $start];
        $http = new \GuzzleHttp\Client();
        $post = ['body' => json_encode($data), 'headers' => ['Content-Type:multipart/form-data']];
        try{
            $res    = $http->post($url, $post);
            $body   = $res->getBody();  // 字符串
            $header = $res->getHeaders(); // 数组
            $bodys  = json_decode($body, 1);
            if($bodys['code'] == 200){
                $data = $bodys['data'];

                //var_dump($data['d3']);
                return $data;
            } else{
                die($bodys['msg']);
            }

        } catch(\Exception $e){
            return [];
        }
    }

    // 查询所有的风向标
    protected function getWinds()
    {
        $windDb = new Wind();
        $winds  = $windDb->isCache(true)->getAll();

        return $winds;
    }

    // 生成搜索引擎数据
    protected function xunsearch($start = 0, $number = 100)
    {
        // 查询快讯
        $this->comment('  生成搜索引擎数据：第'.$start.'条开始…………');
        $userDb   = new User();
        $dispatch = new \App\Models\Dispatch();
        $fields   = ['id', 'title', 'uid', 'is_major', 'ctime', 'content',];  //apply_type  'stock_id', 'topic_id',
        $lists    = $dispatch->where('id', '>=', $start)->select($fields)->limit($number)->get()->toArray();
        if(empty($lists)){
            return true;
        }

        // 在uid上面添加几个数字，构建多个用户的，用于测试查询
        $search = (new Xunsearch())->setDb('dispatch');
        foreach($lists as $key => $item){
            // 判断是否已经采集
            $query  = "id:{$item['id']}";
            $result = $search->search($query);
            if(!empty($result)){
                break;
            }

            if($item['uid']){
                $uinfo = $userDb->isCache(true)->getOneById($item['uid']);
            }

            // 重新组合
            $item['apply_type'] = $uinfo['apply_type'] ?? 0;

            // 创建索引
            $res = $search->add($item);
        }

        return true;
    }

    // 转移的数据库
    protected function toDb()
    {
        if(empty($this->toDb)){
            $this->toDb = DB::connection('mysql');
        }

        return $this->toDb;
    }

    // sql日志
    protected function sqlLog()
    {
        // 保存sql语句到日志中
        $queries = DB::getQueryLog();
        foreach($queries as $query){
            $sql = str_replace('?', '\'%s\'', $query['query']);
            $sql = vsprintf($sql, $query['bindings']);
            $log = 'SQL: '.$sql.'; [RunTime:'.$query['time'].'ms]';
            Log::info($log);
        }

        // 是否内存
        DB::flushQueryLog();
    }

    public function _handle()
    {
        // 输出信息
        $this->line('准备各种颜色的输出信息');
        $this->line('line <info>info</info> <error>error</error> <comment>comment</comment> <question>question</question>');
        $this->info('This is info');
        $this->error('This is error');
        $this->comment('This is comment');
        $this->question('This is question');
        $this->line("1\n2\n");

        // 在 storage/app/logs中
        // Log::info('command:name命令执行 | 这里是命令任务');

        return true; // return 语句是不会展示出来的
    }

}
